#ifndef PERSISTENCE_H
#define PERSISTENCE_H

#include "../mimetypes/mimetype.h"

#include <QtCore/QHash>
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>

QT_BEGIN_NAMESPACE
class QUrl;
QT_END_NAMESPACE

namespace core
{
class IDocument;
class IPersistenceAssistant;
class IPersistentDocument;
class IStorage;

enum DocumentOperation
{
    NONE = 0x0, // ASSERT
    OPEN = 0x1,
    SAVE = 0x2
};

class Persistence
{
public:
    ~Persistence();

    static void initialize();
    static void dispose();

    static void registerStorage(const IStorage* storage);

    static void registerAssistant(const MimeType& mimeType,
        const IPersistenceAssistant* assistant);

    static QSharedPointer<IPersistenceAssistant> getNativeAssistant(
        const QSharedPointer<IPersistentDocument>& document);
    static QSharedPointer<IPersistenceAssistant> getNativeAssistant(
        const QSharedPointer<IDocument>& document,
        const QString& storageName);
    static QList<QSharedPointer<IPersistenceAssistant> > getNativeAssistants(
        const QSharedPointer<IDocument>& document);
    static QSharedPointer<IPersistenceAssistant> getAssistant(
        const QSharedPointer<IPersistentDocument>& document,
        const MimeType& mimeType,
        uint operation);
    static QSharedPointer<IPersistenceAssistant> getAssistant(
        const QSharedPointer<IDocument>& document, const QString& storageName,
        const MimeType& mimeType, uint operation);

    static void closeAssistant(
        const QSharedPointer<IPersistenceAssistant>& assistant);
    static void closeAssistants(
        const QSharedPointer<IDocument>& document);

    static uint liveAssistants(
        const QSharedPointer<IDocument>& document);
    static uint liveAssistants();

    static QSharedPointer<IDocument> open(
        const QSharedPointer<IPersistentDocument>& document);
    static QSharedPointer<IDocument> openAs(
        const QSharedPointer<IPersistentDocument>& document,
        const MimeType& mimeType);

    static QSharedPointer<IPersistentDocument> save(
        const QSharedPointer<IDocument>& document,
        const QString& storageName, bool& canceled);
    static QSharedPointer<IPersistentDocument> saveAs(
        const QSharedPointer<IDocument>& document, const QString& storageName,
        const MimeType& mimeType);

    static QSharedPointer<IPersistentDocument> createDocument(
        const QUrl& url, const QString& storageName);
    static bool deleteDocument(QSharedPointer<IPersistentDocument>&
        document);

    static IStorage* getStorage(const QString& storageName);
    static QHash<QString, QString> registeredStorages();

private:
    Persistence();

public:
    static const QString WILD_CARD;

private:
    QHash<MimeType, QHash<QString, QList<IPersistenceAssistant* > > >
        m_registeredAssistants;
    QHash<MimeType, QHash<QString, IPersistenceAssistant* > >
        m_registeredNativeAssistants;

    QHash<QString, IStorage* > m_registeredStorages;

    QList<QSharedPointer<IPersistenceAssistant> > m_liveAssistants;
};

}

#endif
